package com.lanxiao.cloud.modules.dept.application.assembler;

import com.lanxiao.cloud.common.core.dto.UserBaseDto;
import com.lanxiao.cloud.common.core.utils.TreeUtils;
import com.lanxiao.cloud.common.fill.FillAppointment;
import com.lanxiao.cloud.common.fill.FillHandle;
import com.lanxiao.cloud.common.fill.FillHandleFactory;
import com.lanxiao.cloud.common.fill.FillType;
import com.lanxiao.cloud.modules.dept.application.dto.BasicsDeptTreeDto;
import com.lanxiao.cloud.modules.dept.application.dto.DeptCmdAdd;
import com.lanxiao.cloud.modules.dept.application.dto.DeptCmdUpdate;
import com.lanxiao.cloud.modules.dept.application.dto.DeptDto;
import com.lanxiao.cloud.modules.dept.application.dto.DeptTreeDto;
import com.lanxiao.cloud.modules.dept.domain.model.Dept;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
import org.springframework.stereotype.Component;

/**
 * @author ：qiaoliang
 * @date ：2021-10-26
 */
@Component
public class DeptAssembler {

  private final FillHandleFactory fillHandleFactory;

  public DeptAssembler(FillHandleFactory fillHandleFactory) {
    this.fillHandleFactory = fillHandleFactory;
  }

  public Dept toDept(DeptCmdAdd add) {
    return DeptConverter.INSTANCE.toDept(add);
  }

  public Dept toDept(Long id, DeptCmdUpdate update) {
    Dept dept = DeptConverter.INSTANCE.toDept(update);
    dept.setId(id);
    return dept;
  }

  public List<DeptDto> toDeptDto(List<Dept> list) {
    return DeptConverter.INSTANCE.toDeptDto(list);
  }

  public List<BasicsDeptTreeDto> toDeptUserTreeDto(List<Dept> list) {
    return TreeUtils.buildByRecursive(DeptConverter.INSTANCE.toDeptUserTreeDto(list),1L);
  }

  public List<DeptTreeDto> toDeptTreeDto(List<Dept> list) {
    List<DeptTreeDto> deptTreeDtos = DeptConverter.INSTANCE.toDeptTreeDto(list);
    List<FillAppointment<DeptTreeDto, UserBaseDto<Long>>> fillAppointments = new ArrayList<>();
    List<Function<DeptTreeDto,Long>> functions = new ArrayList<>();
    fillAppointments.add(DeptTreeDto::setCreateUser);
    fillAppointments.add(DeptTreeDto::setUpdateUser);
    functions.add(o->o.getCreateUser().getId());
    functions.add(o->o.getUpdateUser().getId());
    fillHandleFactory.fill(deptTreeDtos, new FillHandle<>(FillType.USER_INFO, fillAppointments, functions));
    return TreeUtils.buildByRecursive(deptTreeDtos, 1L);
  }

  @Mapper
  public interface DeptConverter {

    DeptConverter INSTANCE = Mappers.getMapper(DeptConverter.class);

    @Mappings({
        @Mapping(source = "createBy", target = "createUser.id"),
        @Mapping(source = "updateBy",target = "updateUser.id")
    })
    DeptTreeDto toDeptTreeDto(Dept dept);
    List<DeptTreeDto> toDeptTreeDto(List<Dept> dept);

    BasicsDeptTreeDto toDeptUserTreeDto(Dept dept);
    List<BasicsDeptTreeDto> toDeptUserTreeDto(List<Dept> dept);

    DeptDto toDeptDto(Dept dept);
    List<DeptDto> toDeptDto(List<Dept> dept);

    Dept toDept(DeptCmdUpdate update);
    Dept toDept(DeptCmdAdd add);

  }

}
